#include <vector>
#include <iostream>
#include <random>
#include <stack>
#include <typeinfo>
#include <queue>
#include <string>
#include <cmath>

using namespace std;

void exitabnormal()

{
    cout << "Error." << endl;
}

int priority(string str)
{
    char a = str[0];
    switch (a)
    {
    case '+':
        return 1;
        break;
    case '-':
        return 1;
        break;
    case '*':
        return 2;
        break;
    case '/':
        return 2;
        break;
    case '(':
        return 3;
    case ')':
        return 4;
    default:
        return 0;
        break;
    };
}

class ele
{
public:
    float shu;
    string ope;
    int type; //1weishu 0 wei caozuo
};

int islegal(char ch)
{
    if (ch >= '0' && ch <= '9')
        return 1;
    if (ch == '.')
        return 1;
    if (ch == '+')
        return 1;
    if (ch == '-')
        return 1;
    if (ch == '*')
        return 1;
    if (ch == '/')
        return 1;
    if (ch == '(')
        return 1;
    if (ch == ')')
        return 1;
    return 0;
}

ele calculate(ele b1, ele b2, ele b3)
{
    ele new1;
    new1.type = 1;
    char a = b2.ope[0];

    switch (a)
    {
    case '+':
        new1.shu = b1.shu + b3.shu;
        return new1;
        break;
    case '-':
        new1.shu = b1.shu - b3.shu;
        return new1;
        break;
    case '*':
        new1.shu = b1.shu * b3.shu;
        return new1;
        break;
    case '/':
        new1.shu = b1.shu / b3.shu;
        return new1;
        break;
    default:
        return new1;
        break;
    }
};

void eraseillegal(string &s1)
{
    for (int i = s1.size() - 1; i >= 0; i--)
    {
        int istrue;
        istrue = islegal(s1[i]);
        if (istrue == 0)
        {
            s1.erase(i, 1);
        }
    }
};

int transfloat(string &s1, queue<ele> &q)
{
    int re = 1;
    int n = 0;
    float s = 0;
    int state = 0; ///表示目前数字处于小数第几位
    int flag = 0;
    int weishu = 0;
    int xiaoshu = 0; //检查两个小数中间是否全为数字
    int error = 2;   ///检查小数点相邻格式是否合理 0代表刚刚读过数字 1代表刚刚读过小数点 2代表刚刚读过操作符
    ///错误情况：1、小数点后运算符 2、运算符后小数点  3、小数点后小数点
    ele trans;
    for (int i = 0; i < s1.size(); i++)
    {

        if (s1[i] >= '0' && s1[i] <= '9')
        {

            if (state == 0)
            {
                n = 10 * n + s1[i] - '0';
                flag = 1;
            }
            else
            {
                s = s + (s1[i] - '0') / (pow(10.0, state));
                state++;
                flag = 1;
            }
            if (i == s1.size() - 1)
            {
                trans.shu = n + s;
                trans.type = 1;
                q.push(trans);
            }
            error = 0;
        }
        else
        {
            if (s1[i] == '.')
            {
                if (xiaoshu == 1)
                {
                    exitabnormal();
                    return 0;
                }
                if (error != 0)
                {
                    exitabnormal();
                    return 0;
                }
                state = !state;
                error = 1;
                xiaoshu = 1;
            }
            else
            {
                if (error == 1)
                {
                    exitabnormal();
                    return 0;
                }
                state = 0;
                if (flag == 1)
                {

                    flag = 0;
                    trans.shu = n + s;
                    trans.type = 1;
                    q.push(trans);
                    trans.ope = s1[i];
                    trans.type = 0;
                    q.push(trans);
                    n = 0;
                    s = 0;
                }
                else
                {
                    trans.ope = s1[i];
                    trans.type = 0;
                    q.push(trans);
                }
                error = 2;
                xiaoshu = 0;
            }
        }
    }
    return re;
};

int nix_to_post(queue<ele> &q, queue<ele> &q2, stack<ele> &stack1)
{
    int re = 1;
    ele next;
    int amount = 0; ///未匹配到右括号的左括号个数

    while (!q.empty())
    {

        next = q.front();

        if (next.type == 1)
            q2.push(next);
        else
        {

            if (stack1.empty())
                stack1.push(next);
            else
            {
                if (priority(next.ope) == 3) ///左括号的清醒
                {
                    stack1.push(next);
                    amount++;
                }
                else
                {
                    if (priority(next.ope) == 4) ///右括号时，弹出一个
                    {
                        amount--;
                        if (amount < 0)
                        {
                            exitabnormal();
                            return 0;
                        }

                        while (priority(stack1.top().ope) != 3)
                        {
                            q2.push(stack1.top());
                            stack1.pop();
                        }
                        stack1.pop();
                    }

                    else
                    {
                        if (priority(next.ope) <= priority((stack1.top()).ope) && (priority((stack1.top()).ope) != 3) && (priority((stack1.top()).ope) != 4))
                        {

                            q2.push(stack1.top());
                            stack1.pop();
                            stack1.push(next);
                        }
                        else
                        {
                            stack1.push(next);
                        }
                    }
                }
            }
        }

        q.pop();
    }
    if (amount > 0)
    {
        exitabnormal();
        return 0;
    }

    while (!stack1.empty())
    {
        q2.push(stack1.top());
        stack1.pop();
    }
    return re;
}

int calculateros(stack<ele> &stack2, queue<ele> &q2)
{
    int re = 1;
    ele d1, d2;
    while (!q2.empty())
    {
        if (q2.front().type == 1) ///如果为数字 直接放入堆栈
            stack2.push(q2.front());

        else
        {
            if (stack2.empty())
            {
                exitabnormal();
                return 0;
            }
            d1 = stack2.top();
            stack2.pop();
            if (stack2.empty())
            {
                exitabnormal();
                return 0;
            }
            d2 = stack2.top();
            stack2.pop();
            if (d2.type != 1 || d1.type != 1)
            {
                exitabnormal();
                return 0;
            }
            stack2.push(calculate(d2, q2.front(), d1));
        }

        q2.pop();
    };
    return re;
}

int total_calcu(string &s1)
{
    int a;
    queue<ele> q;
    queue<ele> q2;
    stack<ele> stack1;
    stack<ele> stack2;

    eraseillegal(s1); ///清除非法字符

    a = transfloat(s1, q); ///转化浮点数
    if (a == 0)
        return 0;
    a = nix_to_post(q, q2, stack1); ///中缀变后缀
    if (a == 0)
        return 0;
    a = calculateros(stack2, q2); ///后缀开始计算
    if (a == 0)
        return 0;
    cout << stack2.top().shu << endl;
    return 0;
}
